import uvicorn
from fastapi import FastAPI, Request
from starlette.middleware.cors import CORSMiddleware

from common.logger import logger

import json
import multiprocessing
from common.request_limit import allow_request
from database.proxy_pool_table import ProxyPoolTable
from manager.auth_manager import AuthManager
import random
# from tools.take_su_account.su_login import take_account

from manager.proxy_manager import ProxyManager
from fastapi.responses import HTMLResponse

app = FastAPI()

# 设置允许访问的域名
origins = ["*"]  # 也可以设置为"*"，即为所有。

# 设置跨域传参
app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,  # 设置允许的origins来源
    allow_credentials=True,
    allow_methods=["*"],  # 设置允许跨域的http方法，比如 get、post、put等。
    allow_headers=["*"],
)  # 允许跨域的headers，可以用来鉴别来源等作用。

#设置响应头编码为utf-8
@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
    response = await call_next(request)
    response.headers["Content-Type"] = "application/json; charset=utf-8"
    return response

auth_manager = AuthManager()
proxy_manager_list = []

def make_error(host, msg):
    logger.warning(f"response: host: {host}, msg: {msg}")
    return {"code": -1, "msg": msg, "data": None}

def make_success(host, ips, update_time, format, limit):
    logger.info(f"response: host: {host}, msg: success, limit: {limit}, format: {format}, update_time: {update_time}")
    if limit > 0:
        limit = min(limit, len(ips))
        ips = random.sample(ips, limit)
    if format == "txt":
        ipStr = "\n".join(ips)
        return HTMLResponse(content=ipStr, status_code=200)

    return {"code": 0, "msg": "success", "count": len(ips), "update_time": update_time, "data": ips}

def find_proxy_manager(type: str):
    for proxy_manager in proxy_manager_list:
        if proxy_manager.proxy_type() == type:
            return proxy_manager
    return None

@app.get("/api/proxy/white")
def api_proxy(type: str ="shared2", format: str = "json", limit: int = 0, request: Request = None):
    logger.info(f"request: /api/proxy/white, host: {request.client.host}")
    try:
        auth_manager.auth_white(request.client.host)
    except Exception as e:
        return make_error(request.client.host, str(e))
    
    matched_proxy_manager = find_proxy_manager(type)
    if not matched_proxy_manager:
        return make_error(request.client.host, f"代理类型 {type} 不存在")
    
    return make_success(request.client.host, matched_proxy_manager.get_all_proxy(), matched_proxy_manager.update_time(), format, limit)

@app.get("/api/proxy/key")
def api_proxy(key: str, type: str ="shared2", format: str = "json", limit: int = 0, request: Request = None):
    logger.info(f"request: /api/proxy/key, host: {request.client.host}, key: {key}")
    try:
        auth_manager.auth_key(key)
    except Exception as e:
        return make_error(request.client.host, str(e))
    
    matched_proxy_manager = find_proxy_manager(type)
    if not matched_proxy_manager:
        return make_error(request.client.host, f"代理类型 {type} 不存在")
    
    return make_success(request.client.host, matched_proxy_manager.get_all_proxy(), matched_proxy_manager.update_time(), format, limit)

@app.get("/api/proxy")
def api_proxy(type: str = "shared2", key: str = None, format: str = "json", limit: int = 0, request: Request = None):
    logger.info(f"request: /api/proxy, host: {request.client.host}, key: {key}, type: {type}, limit: {limit}")
    try:
        if not key:
            auth_manager.auth_white(request.client.host)
        else:
            auth_manager.auth_key(key)
    except Exception as e:
        return make_error(request.client.host, str(e))
    
    matched_proxy_manager = find_proxy_manager(type)
    if not matched_proxy_manager:
        return make_error(request.client.host, f"代理类型 {type} 不存在")
    
    ips = matched_proxy_manager.get_all_proxy()
    update_time = matched_proxy_manager.update_time()
    
    return make_success(request.client.host, ips, update_time, format, limit)

if __name__ == "__main__":
    
    shared_proxy = {
        "url" : "http://ip.api.466ip.cn:466/ProxyiPAPI.aspx?action=GetIP&OrderNumber=0707f8da43171e90c13925ba7de21c430a6b&qty=200",
        "interval" : 1,
        "fetch_count" : 30,
        "type" : "shared",
    }
    
    shared2_proxy = {
        "url" : "http://dw.tiqu.letecs.com/getip_cm?&big_num=650&poolstr=73,74,75&type=1&pro=&city=0&yys=0&port=1&pack=336495&ts=0&ys=0&cs=0&lb=1&sb=0&pb=4&mr=1&regions=&code=w6puxefvj1",
        "interval" : 1,
        "fetch_count" : 20,
        "type" : "shared2",
    }
    
    #proxy_manager_list.append(ProxyManager(shared_proxy))
    proxy_manager_list.append(ProxyManager(shared2_proxy))
    
    with ProxyPoolTable() as db:
        db.truncate()
        db.commit()

    for proxy_manager in proxy_manager_list:
        proxy_manager.active()

    uvicorn.run(app, host="0.0.0.0", port=9669)
